using System;
using System.Data.SqlClient;

namespace DotConferenceSql
{
    /// <summary>
    /// Create a new SqlQuery
    /// 
    /// It create a SqlCommand ready to use. It also manage the
    /// DatabaseConnection object.
    /// </summary>
    /// <example>
    /// <![CDATA[
    /// using (SqlQuery testQuery = new SqlQuery())
    /// {
    ///    SelectQueryElement selectElement = new SelectQueryElement();
    ///    selectElement.Add("name");
    ///    testQuery.Elements.Add(selectElement);
    ///    testQuery.Elements.Add(new FromTableQueryElement("AssignedJob"));
    ///    testQuery.Elements.Add(new CustomWhereStatement("id = 5"));
    ///
    ///    SqlCommand theCommand = testQuery.BuildSqlCommand();
    ///
    ///    try
    ///    {
    ///        string readValue = theCommand.ExecuteScalar().ToString();
    ///        MessageBox.Show(readValue);
    ///    }
    ///    catch (SqlException ex)
    ///    {
    ///        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    ///    }
    /// }
    /// ]]>
    /// </example>
    public class SqlQuery : CompositeQueryElement, IDisposable
    {
        private DatabaseConnection m_connection = null;
        private bool m_useInternalConnection = true;

        /// <summary>
        /// Initializes a new instance of the <see cref="SqlQuery"/> class.
        /// </summary>
        public SqlQuery()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SqlQuery"/> class.
        /// </summary>
        /// <param name="useInternalConnection">if set to <c>true</c>, use internal connection.</param>
        public SqlQuery(bool useInternalConnection)
        {
            m_useInternalConnection = useInternalConnection;
        }

        /// <summary>
        /// Builds a SqlCommand instance based on elements
        /// contained in this element.
        /// </summary>
        /// <returns>SqlCommand ready to use</returns>
        public SqlCommand BuildSqlCommand()
        {
            SqlCommand newCommand = new SqlCommand();
            if (m_useInternalConnection)
            {
                m_connection = DatabaseManager.Instance.GetConnection();
                newCommand.Connection = m_connection;
            }
            newCommand.CommandText = BuildTextQuery();

            System.Diagnostics.Debug.WriteLine("BuildSqlCommand(): " + newCommand.CommandText);

            if (newCommand.CommandText == String.Empty)
            {
                throw new ArgumentException("The generated query is empty.");
            }
            // List param in CompositeSearchElement
            foreach (SqlParameter param in ListParameters())
            {
                newCommand.Parameters.Add(param);
            }

            return newCommand;
        }

        #region IDisposable Membres

        /// <summary>
        /// Closes the database connection on resource release
        /// </summary>
        public void Dispose()
        {
            System.Diagnostics.Debug.WriteLine("QNSL.LibCrewCalling.SqlQuery.Dispose()");
            if (m_connection != null)
            {
                m_connection.Dispose();
            }
        }

        #endregion
    }
}